package com.xhwl.logistics.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.UUID;

/**
 * @author Aaronloo
 * @description AES对称加密
 * 1、keyGenerate生成密钥，AES对称加密，即加解密使用同一个密钥
 * 2、encrypt(密钥, 明文)，对明文进行加密，对加密后的数据进行Base64编码
 * 3、decrypt(密钥, 密文)，对密文进行解密，密文是加密后进行了Base64编码的数据
 * @create 2020/12/10
 */
public class AESUtil {

    private static final String KEY_ALGORITHM = "AES";
    private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    /**
     * @return String 对生成的密钥进行了Base64编码的字符串
     */
    public static String keyGenerate() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
        keyGenerator.init(new SecureRandom());
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] keyBytes = secretKey.getEncoded();
        //return Hex.encodeHexString(keyBytes);
        return Base64.getEncoder().encodeToString(keyBytes);
    }

    /**
     * @param keyStr 进行了Base64编码的密钥
     * @param data   数据明文
     * @return String 数据密文，加密后的数据，进行了Base64的编码
     */
    public static String encrypt(String keyStr, String data) throws Exception {
        //转换密钥
        //Key key = new SecretKeySpec(Hex.decodeHex(keyStr), KEY_ALGORITHM);
        //System.out.println("encrypt->Base64.getDecoder().decode(keyStr):\n" + Base64.getDecoder().decode(keyStr) + "\n");
        Key key = new SecretKeySpec(Base64.getDecoder().decode(keyStr), KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        //加密
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] result = cipher.doFinal(data.getBytes("UTF-8"));
        //return Hex.encodeHexString(result);
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * @param keyStr 进行了Base64编码的密钥
     * @param data   数据密文（数据必须是通过AES进行加密后，对加密数据Base64编码的数据）
     * @return String 数据明文
     */
    public static String decrypt(String keyStr, String data) throws Exception {
        //转换密钥
        //Key key = new SecretKeySpec(Hex.decodeHex(keyStr), KEY_ALGORITHM);
        Key key = new SecretKeySpec(Base64.getDecoder().decode(keyStr), KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        //解密
        cipher.init(Cipher.DECRYPT_MODE, key);
        //byte[] result = cipher.doFinal(Hex.decodeHex(data));
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(data));
        return new String(result, "UTF-8");
    }

    public static void main(String[] args) throws Exception {
        UUID uuid = UUID.randomUUID();
        //密钥//
        String key2 = "wNXq6H8bwE6zG0Ne+RmCLA==";
        //原文
        String textIn = "{\"recordId\":\""+uuid+"\"," +
                "\"status\":0," +
                "\"projectId\":1320," +
                "\"projectName\":\"上海金茂学校xiugia\"," +
                "\"projectCode\":\"X00001320\"," +
                "\"plateNumber\":\"粤B98071\"," +
                "\"ownerName\":\"小头子\"," +
                "\"ownerPhone\":\"13691963888\"," +
                "\"cardType\":0," +
                "\"enterPicUrl\":\"https://pic3.zhimg.com/v2-a15a10dd189783cc6204aee6dd1c9890.webp\"," +
                "\"enterTime\":\"2020-04-05 12:12:12\"," +
                "\"enterType\":1," +
                "\"enterPassage\":\"Rainbow通道\"," +
                "\"enterPassageId\":30}";




        String textOut = "{\"recordId\":\"e823dc77-be6f-46ed-99db-0a342976445e\"," +
                "\"status\":1," +
                "\"projectId\":1320," +
                "\"projectName\":\"上海金茂学校xiugia\"," +
                "\"projectCode\":\"X00001320\"," +
                "\"plateNumber\":\"粤B98071\"," +
                "\"ownerName\":\"小头子\"," +
                "\"ownerPhone\":\"13691963888\"," +
                "\"cardType\":0," +
                "\"enterPicUrl\":\"https://pic3.zhimg.com/v2-a15a10dd189783cc6204aee6dd1c9890.webp\"," +
                "\"enterTime\":\"2020-04-05 12:12:12\"," +
                "\"enterType\":1," +
                "\"enterPassage\":\"Rainbow通道\"," +
                "\"enterPassageId\":30,"+
                "\"recordId\":\"20210422121212\"," +
                "\"status\":1," +
                "\"existPicUrl\":\"https://blog.csdn.net/huanhuanq1209/article/details/80899017\"," +
                "\"existTime\":\"2020-04-08 10:10:12\"," +
                "\"existPassage\":\"Rainbow通道333\"," +
                "\"existPassageId\":31," +
                "\"existType\":1}";
        String test="{\n" +
                "  \"areaName\": [\n" +
                "    \"A区\",\n" +
                "    \"B区\"\n" +
                "  ],\n" +
                "  \"enterpriseId\": 248,\n" +
                "  \"id\": 0,\n" +
                "  \"industryType\": \"SCH\",\n" +
                "  \"level\": 2,\n" +
                "  \"name\": \"金茂测试x车场\",\n" +
                "  \"projectId\": 1248,\n" +
                "  \"projectOrgId\": 2466,\n" +
                "}";


        //加密
        String encryptStr = encrypt(key2, textIn);
        //解密
        String decryptStr = decrypt(key2, encryptStr);
        System.out.println("encryptStr:\n" + encryptStr + "\n\ndecryptStr:\n" + decryptStr);
        System.out.println("keyGenerate() = " + keyGenerate());

    }

    /**
     * 大华ICC专属的解密方式
     */
    public static String daHuaICCDecrypt(String str, HttpServletRequest request)throws Exception{
        //解密，使用的是大华ICC专属解密方式。
        str = URLDecoder.decode(str, "utf-8");
        str = str.replace(" ","+");
        String userAgent = request.getHeader("User-Agent");
        userAgent = userAgent.substring(userAgent.lastIndexOf("_") + 1, userAgent.length());
        String[] nums = userAgent.split("[\\D]+");
        int ciphertnum=0;
        String lastNum = nums[nums.length - 1];
        if(lastNum.length()>1){
            lastNum = lastNum.substring(lastNum.length() - 1, lastNum.length());
        }
        ciphertnum = Integer.parseInt(lastNum);
        String key = userAgent.substring(ciphertnum, ciphertnum + 16);
        byte[] raw = key.getBytes("utf-8");
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE,skeySpec);
        byte[] decode = new org.apache.commons.codec.binary.Base64().decode(str);
        byte[] bytes = cipher.doFinal(decode);
        String s = new String(bytes, "utf-8");
        return s;
    }

}
